Amazon SageMaker AutopilotのチュートリアルのJob関連の設定を変更して動かしてみた
皆さん、こんにちは。
クルトンです!
今回は、Amazon SageMaker Autopilot(以下、Autopilot)をチュートリアルを見て動かしてみました。Autopilotでは、複数のモデルを学習させ、一番より良い予測精度をもったモデルを使った予測も行なえます。
前提
公式チュートリアルを動かしています。
実行環境は、SageMaker StudioのPython 3 (Data Science)カーネルです。
準備
まずは各メソッドを呼び出すのに必要なboto3など、必要なモジュールをimportします。 変数prefixについては、チュートリアルそのままとしていますが、別名を設定しても良いです。ここを変更する事で、S3へデータをアップロードする時のパスが変わります。
import sagemaker import boto3 from sagemaker import get_execution_role region = boto3.Session().region_name session = sagemaker.Session() bucket = session.default_bucket() prefix = "sagemaker/autopilot-dm" role = get_execution_role() sm = boto3.Session().client(service_name="sagemaker", region_name=region)
分析対象のファイル準備
Autopilotで学習させるデータを用意します。wgetコマンドを使って公式が用意しているデータをダウンロードします。 公式ドキュメントによると、CSVファイルかParquetファイルをサポートしているとの事なので、ダウンロードしたzipファイルを解凍して、CSVファイルを取り出す必要があります。
!apt-get install unzip # 同じ階層に保存(ファイル名: bank-additonal.zip) !wget -N https://sagemaker-sample-data-us-west-2.s3-us-west-2.amazonaws.com/autopilot/direct_marketing/bank-additional.zip !unzip -o bank-additional.zip local_data_path = "./bank-additional/bank-additional-full.csv"
Amazon S3へファイルアップロード
ダウンロードしてきたデータを、学習用とテスト用の2つに分け、Autopilotで扱えるようにS3へデータをアップロードします。
データ読み込み
CSVファイルを読み込むため、pandasモジュールのread_csvメソッドを使います。
import pandas as pd data = pd.read_csv(local_data_path) pd.set_option("display.max_columns", 500) # 全カラムを見えるよう設定 pd.set_option("display.max_rows", 10) # 1ページで収まるように行数を設定 data # データを出力して確認
データ分割
次に、データを学習用とテスト用の2つに分割します。
train_data = data.sample(frac=0.8, random_state=200) test_data = data.drop(train_data.index) test_data_no_target = test_data.drop(columns=["y"])
S3へアップロード
最後に、分割したデータをS3へアップロードします。学習用のデータとテスト用のデータについて、headerの有無の設定が異なるので、他のデータを使う場合に注意が必要そうです。
train_file = "train_data.csv" train_data.to_csv(train_file, index=False, header=True) train_data_s3_path = session.upload_data(path=train_file, key_prefix=prefix + "/train") print("Train data uploaded to: " + train_data_s3_path) test_file = "test_data.csv" test_data_no_target.to_csv(test_file, index=False, header=False) test_data_s3_path = session.upload_data(path=test_file, key_prefix=prefix + "/test") print("Test data uploaded to: " + test_data_s3_path)
AutopilotのJob設定
ここでは、AutopilotでのJobに関連する設定を行ないます。次の公式ドキュメントが参考になります。
変数auto_ml_job_configで設定しているCompletionCriteria
では、他にも1つのJobが完了するまでの時間を制限する事も可能です。
auto_ml_job_config = {"CompletionCriteria": {"MaxCandidates": 10}} input_data_config = [ { "DataSource": { "S3DataSource": { "S3DataType": "S3Prefix", "S3Uri": f"s3://{bucket}/{prefix}/train", } }, "TargetAttributeName": "y", } ] output_data_config = {"S3OutputPath": f"s3://{bucket}/{prefix}/output"}
注意点
データの前処理とハイパーパラメータのTrainingJobの2種類が動き、CompletionCriteria
で設定したMaxCandidatesの数に2を掛けた20個のTrainingJob数が動きました。また、関連して、ProcessingJobが複数動きます。
「とにかくコストを小さくして動かしたい」といった場合は、3など小さな数字を設定する事が可能です。ただし、予測の精度が落ちる可能性ありますので、ご留意ください。
AutopilotのJobを開始
実際にAutopilotを使って、機械学習モデルの学習とハイパーパラメータのチューニングを行ないます。どのような予測をさせるのかが分かっている場合は、create_auto_ml_jobメソッドのProblemTypeで指定できます。指定できるタイプは、BinaryClassification(2値分類)とMulticlassClassification(多クラス分類)とRegression(回帰)の3つです。
from time import gmtime, strftime, sleep timestamp_suffix = strftime("%d-%H-%M-%S", gmtime()) auto_ml_job_name = "automl-banking-" + timestamp_suffix print("AutoMLJobName: " + auto_ml_job_name) sm.create_auto_ml_job( AutoMLJobName=auto_ml_job_name, InputDataConfig=input_data_config, OutputDataConfig=output_data_config, AutoMLJobConfig=auto_ml_job_config, RoleArn=role, )
Jobの詳細を出力
create_auto_ml_jobメソッドを動かしたのち、各Jobの状態を次のコードを使うと確認できます。 マネージメントコンソールからも、学習中などのJobのステータスが確認可能です。
print("JobStatus - Secondary Status") print("------------------------------") describe_response = sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name) print(describe_response["AutoMLJobStatus"] + " - " + describe_response["AutoMLJobSecondaryStatus"]) job_run_status = describe_response["AutoMLJobStatus"] while job_run_status not in ("Failed", "Completed", "Stopped"): describe_response = sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name) job_run_status = describe_response["AutoMLJobStatus"] print( describe_response["AutoMLJobStatus"] + " - " + describe_response["AutoMLJobSecondaryStatus"] ) sleep(30)
Jobのステータスは次のようになりました。出力例としてご確認ください。
JobStatus - Secondary Status ------------------------------ InProgress - AnalyzingData InProgress - AnalyzingData InProgress - AnalyzingData InProgress - AnalyzingData InProgress - AnalyzingData …… InProgress - AnalyzingData InProgress - FeatureEngineering InProgress - FeatureEngineering InProgress - FeatureEngineering …… InProgress - FeatureEngineering InProgress - ModelTuning InProgress - ModelTuning InProgress - ModelTuning …… InProgress - ModelTuning InProgress - MergingAutoMLTaskReports InProgress - MergingAutoMLTaskReports InProgress - MergingAutoMLTaskReports …… InProgress - MergingAutoMLTaskReports Completed - Completed
学習結果確認
複数のモデルを学習した結果から、一番予測精度が高いモデルを確認します。
best_candidate = sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)["BestCandidate"] best_candidate_name = best_candidate["CandidateName"] print(best_candidate) print("\n") print("CandidateName: " + best_candidate_name) print( "FinalAutoMLJobObjectiveMetricName: " + best_candidate["FinalAutoMLJobObjectiveMetric"]["MetricName"] ) print( "FinalAutoMLJobObjectiveMetricValue: " + str(best_candidate["FinalAutoMLJobObjectiveMetric"]["Value"]) )
次以降のコードでは、ここで確認したモデルを使って推論を実行します。
バッチ推論を実施
まずは推論をさせるためのモデルを、create_modelメソッドでデプロイします。
model_name = "automl-banking-model-" + timestamp_suffix model = sm.create_model( Containers=best_candidate["InferenceContainers"], ModelName=model_name, ExecutionRoleArn=role ) print(f"Model ARN corresponding to the best candidate is : {model['ModelArn']}")
バッチ推論を実施するためtransform_jobを設定後実行
次に、バッチ推論を行なうにあたって、Transformジョブを実行するので、推論を実行するファイルや推論結果を保存するS3 URIを設定します。
transform_job_name = "automl-banking-transform-" + timestamp_suffix transform_input = { "DataSource": {"S3DataSource": {"S3DataType": "S3Prefix", "S3Uri": test_data_s3_path}}, "ContentType": "text/csv", "CompressionType": "None", "SplitType": "Line", } transform_output = { "S3OutputPath": f"s3://{bucket}/{prefix}/inference-results", } transform_resources = {"InstanceType": "ml.m5.4xlarge", "InstanceCount": 1} sm.create_transform_job( TransformJobName=transform_job_name, ModelName=model_name, TransformInput=transform_input, TransformOutput=transform_output, TransformResources=transform_resources, )
次のコードで、推論の途中経過を確認できます。
print("JobStatus") print("----------") describe_response = sm.describe_transform_job(TransformJobName=transform_job_name) job_run_status = describe_response["TransformJobStatus"] print(job_run_status) while job_run_status not in ("Failed", "Completed", "Stopped"): describe_response = sm.describe_transform_job(TransformJobName=transform_job_name) job_run_status = describe_response["TransformJobStatus"] print(job_run_status) sleep(30)
推論の途中経過の出力例は、次のようになります。
JobStatus ---------- InProgress InProgress InProgress InProgress InProgress InProgress InProgress InProgress InProgress InProgress InProgress InProgress Completed
推論結果を確認
バッチ推論が完了すると、出力先に設定したパスへファイルがアップロードされています。 ここでは、S3から推論結果のファイルをダウンロードし、pandasモジュールのread_csvメソッドで読み込み後、データの確認をしています。
<br />s3_output_key = f"{prefix}/inference-results/test_data.csv.out" local_inference_results_path = "inference_results.csv" s3 = boto3.resource("s3") inference_results_bucket = s3.Bucket(session.default_bucket()) inference_results_bucket.download_file(s3_output_key, local_inference_results_path) data = pd.read_csv(local_inference_results_path, sep=";") pd.set_option("display.max_rows", 10) # 1ページで収まるように行数を設定 data
リソース削除
Autopilotでは、さまざまなファイルを作成されるので、それらファイルが必要なければ、次のコードで削除できます。
s3 = boto3.resource('s3') bucket = s3.Bucket(bucket) job_outputs_prefix = '{}/output/{}'.format(prefix,auto_ml_job_name) bucket.objects.filter(Prefix=job_outputs_prefix).delete()
その他
全モデルの学習結果を確認する方法や、Autopilotで実行したジョブが終わると2つのノートブックが作成されます。
全モデルの学習結果を確認
次のコードで、一番良かった学習結果のモデル以外では、どのような学習結果だったかを確認できます。
candidates = sm.list_candidates_for_auto_ml_job( AutoMLJobName=auto_ml_job_name, SortBy="FinalObjectiveMetricValue" )["Candidates"] index = 1 for candidate in candidates: print( str(index) + " " + candidate["CandidateName"] + " " + str(candidate["FinalAutoMLJobObjectiveMetric"]["Value"]) ) index += 1
ノートブック生成場所を確認
生成されるノートブックは次の2つです。
- SageMakerAutopilotCandidateDefinitionNotebook.ipynb
- 前処理に使った設定(カテゴリカルデータのエンコーディング方法)や、ハイパーパラメータの調整時の設定を確認できます。
- SageMakerAutopilotDataExplorationNotebook.ipynb
- 学習に使用されたデータセットの情報が記されています。中央値や平均値といった基本的な統計的情報や、データセットのそれぞれのカラムにおける型を確認できます。
SageMakerAutopilotCandidateDefinitionNotebook.ipynbのパス確認
sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)["AutoMLJobArtifacts"][ "CandidateDefinitionNotebookLocation" ]
SageMakerAutopilotDataExplorationNotebook.ipynbのパス確認
sm.describe_auto_ml_job(AutoMLJobName=auto_ml_job_name)["AutoMLJobArtifacts"][ "DataExplorationNotebookLocation" ]
終わりに
今回は、AutopilotをSageMaker Studioから実行してみました!
簡単に実行できるのでありがたいですね。また、ハイパーパラメータの調整もしてくれるので、予測精度を上げるための処理がなされているのもナイスですね。
今回はここまで。
それでは、また!
参考にしたサイト
【イベント開催のお知らせ】
2023/07/19(水)「DevelopersIO大阪」4年ぶりのオフライン開催決定!
AWSはもちろん、ChatGPTやデータ分析など幅広い分野の技術を取り扱った12のライブセッションをお送りします。
また、クラスメソッドのエンジニアと直接技術の話ができる相談ブースも開設いたします。
大阪オフィス所属のAWS Japan Top Engineersや元Ambassadorも大集合!
さらになんと、数量限定でクラスメソッド社員謹製の本格スパイスカレーを提供いたします!
入場無料、途中の入退室は自由です。ぜひご参加ください!
タイムスケジュール・お申込みはこちらから! https://classmethod.connpass.com/event/286155/